
package com.zdkj.subway.stm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdkj.common.security.service.PigxUser;
import com.zdkj.common.security.util.ObjectUtils;
import com.zdkj.common.security.util.SecurityUtils;
import com.zdkj.subway.stm.constant.StmTableCommon;
import com.zdkj.subway.stm.dto.in.CommomConfirmInfoDTO;
import com.zdkj.subway.stm.dto.in.SwStElectronicReceiptDTO;
import com.zdkj.subway.stm.dto.in.SwStMarketingTicketDTO;
import com.zdkj.subway.stm.entity.*;
import com.zdkj.subway.stm.mapper.SwStMarketingTicketMapper;
import com.zdkj.subway.stm.service.*;
import com.zdkj.subway.stm.util.BeanUtilsStm;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 营销车票录入主表
 *
 * @author songtuo
 * @date 2020-07-11 21:43:57
 */
@Service
@AllArgsConstructor
public class SwStMarketingTicketServiceImpl extends ServiceImpl<SwStMarketingTicketMapper, SwStMarketingTicket> implements SwStMarketingTicketService {

    @Autowired
    SwStMarketingTicketGroupSellService ticketGroupSellService;
    @Autowired
    SwStMarketingTicketOffineSellService offineSellService;
    @Autowired
    SwStMarketingTicketOffineTakeTicketService takeTicketService;
    //@Autowired
    //SwStConductorSettleService settleService;

    /**
     * 电子预览service
     */
    @Autowired
    SwStElectronicReceiptService electronicReceiptService;
    @Autowired
    SwStElectronicReceiptDetailsService detailsService;

    private final SwStMarketingTicketMapper swStMarketingTicketMapper;

    private final SwStmStationDataEntryLogService swStmStationDataEntryLogService;

    @Override
    @Transactional
    public boolean saveSwStMarketingTicket(SwStMarketingTicketDTO stMarketingTicketDTO) {
        //1：日营销车票主表数据添加
        SwStMarketingTicket marketingTicket = stMarketingTicketDTO.getMarketingTicket();
        List<SwStMarketingTicket> existsList = list(Wrappers.<SwStMarketingTicket>lambdaQuery()
                .eq(SwStMarketingTicket::getConductorJobNo, marketingTicket.getConductorJobNo())
                .eq(SwStMarketingTicket::getOpertorTime, marketingTicket.getOpertorTime())
                .eq(SwStMarketingTicket::getConductorShifts, marketingTicket.getConductorShifts())
                .eq(SwStMarketingTicket::getDeviceOperateNum, marketingTicket.getDeviceOperateNum()));
                //.eq(SwStMarketingTicket::getBomCode, marketingTicket.getBomCode()));
        if(existsList.size() > 0){
            throw new RuntimeException("该售票员当日营销车票数据已录入,请勿重复录入！");
        }
        SwStMarketingTicket marketingTicketObj = ObjectUtils.getDefaultObj(SwStMarketingTicket.class);
        BeanUtil.copyProperties(marketingTicketObj, marketingTicket, CopyOptions.create().setIgnoreNullValue(true));
        marketingTicket.setBomCode(BeanUtilsStm.bomOrJobNoSort(marketingTicket.getBomCode()));//bom编号排序后保存
        //设备操作号去空格
        marketingTicket.setDeviceOperateNum(BeanUtilsStm.strRemoveBlank(marketingTicket.getDeviceOperateNum()));
        //团购
        List<SwStMarketingTicketGroupSell> ticketGroupSells = stMarketingTicketDTO.getTicketGroupSells();
        //正常售卖
        List<SwStMarketingTicketOffineSell> ticketOffineSells = stMarketingTicketDTO.getTicketOffineSells();
        //线下明细
        List<SwStMarketingTicketOffineTakeTicket> ticketOffineTakeTickets = stMarketingTicketDTO.getTicketOffineTakeTickets();
        //2: 从表复制公共属性
        BeanUtilsStm.buildProperties(ticketGroupSells);
        BeanUtilsStm.buildProperties(ticketOffineSells);
        BeanUtilsStm.buildProperties(ticketOffineTakeTickets);
        //3:主表属性set
        countSellDetails(marketingTicket, ticketOffineSells,ticketGroupSells,ticketOffineTakeTickets);

        //设置del_flag
        marketingTicket.setDelFlag("0");
        //4:保存主表
        save(marketingTicket);
        //5:保存从表
        Integer rid = marketingTicket.getId();
        if (CollectionUtil.isNotEmpty(ticketOffineSells)) {
            ticketOffineSells.forEach(x -> x.setRelationId(rid));
            offineSellService.saveBatch(ticketOffineSells);
        }
        if (CollectionUtil.isNotEmpty(ticketGroupSells)) {
            ticketGroupSells.forEach(x -> x.setRelationId(rid));
            ticketGroupSellService.saveBatch(ticketGroupSells);
        }
        if (CollectionUtil.isNotEmpty(ticketOffineTakeTickets)) {
            ticketOffineTakeTickets.forEach(x -> x.setRelationId(rid));
            takeTicketService.saveBatch(ticketOffineTakeTickets);
        }
        //TODO 3.1: 同步电子预览数据 因为保存时候需要得到   营销车票子表Id和RelationTd  所以要在保存主表【之后】
        electronicReceiptStatistics(ticketGroupSells,ticketOffineTakeTickets,marketingTicket);

        //电子回执单合计售卖金额
//        if(CollectionUtil.isNotEmpty(ticketGroupSells)){
//            for(SwStMarketingTicketGroupSell ticketGroup : stMarketingTicketDTO.getTicketGroupSells()){
//                if("0".equals(ticketGroup.getPayMethod())&&!CollectionUtil.isNotEmpty(ticketOffineTakeTickets)){
//                    break;
//                }else if("0".equals(ticketGroup.getPayMethod())&&CollectionUtil.isNotEmpty(ticketOffineTakeTickets)){
//                    synElectronicOffineTakeTicket(marketingTicket, ticketOffineTakeTickets);
//                }else{
//                    synElectronicPreviewData(marketingTicket, ticketGroupSells, ticketOffineTakeTickets);
//                }
//            }
//        }else if(CollectionUtil.isNotEmpty(ticketOffineTakeTickets)){
//            synElectronicOffineTakeTicket(marketingTicket, ticketOffineTakeTickets);
//        }

        //6:同步存储 售票员日结算数据 TODO
        //synConductorSettleData(marketingTicket.getRefConductorSettleId(),rid);
        return true;
    }

    /**
     * 统计电子回执单主表数据和同步更新营销车票主表setRefElectronicPreviewId
     * @param ticketGroupSells
     * @param ticketOffineTakeTickets
     * @return
     */
    private void electronicReceiptStatistics(
            List<SwStMarketingTicketGroupSell> ticketGroupSells,
            List<SwStMarketingTicketOffineTakeTicket> ticketOffineTakeTickets,
            SwStMarketingTicket marketingTicket
    ) {
        //电子回执单合计售卖张数
        int totalSellNum = 0;
        //电子回执单合计售卖金额
        BigDecimal totalSellAmount = new BigDecimal("0.00");
        //团购
        if(CollectionUtil.isNotEmpty(ticketGroupSells)){
            totalSellNum = ticketGroupSells.stream().filter(x -> !"0".equals(x.getPayMethod())).mapToInt(SwStMarketingTicketGroupSell::getSellNum).sum();
            totalSellAmount = ticketGroupSells.stream().filter(x -> !"0".equals(x.getPayMethod())).map(SwStMarketingTicketGroupSell::getDiscountAmount).reduce(BigDecimal.ZERO,BigDecimal::add);
        }
        //线下取票
        if(CollectionUtil.isNotEmpty(ticketOffineTakeTickets)){
            totalSellNum += ticketOffineTakeTickets.stream().mapToInt(SwStMarketingTicketOffineTakeTicket::getTicketNum).sum();
            totalSellAmount = totalSellAmount.add(ticketOffineTakeTickets.stream().map(SwStMarketingTicketOffineTakeTicket::getSellAmount).reduce(BigDecimal.ZERO,BigDecimal::add));
        }
        //保存电子回执单主表
        SwStElectronicReceipt receipt = new SwStElectronicReceipt();
        BeanUtils.copyProperties(marketingTicket,receipt);
        receipt.setId(null);
        receipt.setAccountTime(marketingTicket.getOpertorTime());
        receipt.setTotalSellNum(totalSellNum);
        receipt.setTotalSellAmount(totalSellAmount);
        receipt.setTotalTransferAmount(new BigDecimal("0.00"));//合计转账金额先置0
        receipt.setCreateTime(LocalDateTime.now());
        electronicReceiptService.save(receipt);
        //获取到电子回执单主表id
        Integer relationId = receipt.getId();
        //同步到营销车票主表
        marketingTicket.setRefElectronicPreviewId(relationId);
        updateById(marketingTicket);
        //保存电子回执单子表
        List<SwStElectronicReceiptDetails> receiptDetailsList = statisticalElectronicReceiptDetails(ticketGroupSells, ticketOffineTakeTickets, relationId);
        detailsService.saveBatch(receiptDetailsList);
    }

    /**
     * 统计电子回执单子表数据
     * @param ticketGroupSells
     * @param ticketOffineTakeTickets
     * @return
     */
    private List<SwStElectronicReceiptDetails> statisticalElectronicReceiptDetails(
            List<SwStMarketingTicketGroupSell> ticketGroupSells,
            List<SwStMarketingTicketOffineTakeTicket> ticketOffineTakeTickets,
            Integer relationId
    ) {
        List<SwStElectronicReceiptDetails> receiptDetailsList = new ArrayList<>();
        //团购
        if(CollectionUtil.isNotEmpty(ticketGroupSells)){
            List<SwStMarketingTicketGroupSell> ticketGroupSellsList = ticketGroupSells.stream().filter(x -> !"0".equals(x.getPayMethod())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(ticketGroupSellsList)){
                ticketGroupSellsList.forEach(x -> {
                    SwStElectronicReceiptDetails receiptDetails = SwStElectronicReceiptDetails.builder()
                            .relationId(relationId)
                            .ticketType(x.getTicketType())
                            .ticketName(x.getTicketName())
                            .ticketSellNum(x.getSellNum())
                            .ticketSellAmount(x.getDiscountAmount())
                            .ticketWayNum(x.getTicketWayNum())//回执单号
                            .sellWay("2")//团购
                            .marketingId(x.getId())
                            .marketingRelationId(x.getRelationId())
                            .delFlag("0")
                            .build();
                    receiptDetailsList.add(receiptDetails);
                });

            }
        }
        //1转账
        if(CollectionUtil.isNotEmpty(ticketOffineTakeTickets)){
            //只同步转账得数据到电子回执单表
            List<SwStMarketingTicketOffineTakeTicket> ticketOffineTakeTicketList = ticketOffineTakeTickets.stream().filter(x -> "1".equals(x.getTakeTicketWay())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(ticketOffineTakeTicketList)){
                ticketOffineTakeTicketList.forEach(x -> {
                    SwStElectronicReceiptDetails receiptDetails = SwStElectronicReceiptDetails.builder()
                            .relationId(relationId)
                            .ticketType(x.getTicketType())
                            .ticketName(x.getTicketName())
                            .ticketSellNum(x.getTicketNum())
                            .ticketSellAmount(x.getSellAmount())
                            .ticketWayNum(x.getTicketWayNum())
                            .sellWay("0")//电子回执单里 0代表转账
                            .ticketWayNum(x.getTicketWayNum())//回执单号
                            .marketingId(x.getId())
                            .marketingRelationId(x.getRelationId())
                            .delFlag("0")
                            .build();
                    receiptDetailsList.add(receiptDetails);
                });

            }
        }
        return receiptDetailsList;
    }
    /**
     * TODO 同步电子预览数据   弃用
     *
     * @param marketingTicket
     * @param ticketGroupSells
     * @param ticketOffineTakeTickets
     */
    private void synElectronicPreviewData(SwStMarketingTicket marketingTicket, List<SwStMarketingTicketGroupSell> ticketGroupSells, List<SwStMarketingTicketOffineTakeTicket> ticketOffineTakeTickets) {
        List<SwStElectronicReceiptDetails> data = countElectronicPreviewData(ticketGroupSells, ticketOffineTakeTickets);
        SwStElectronicReceipt receipt = new SwStElectronicReceipt();
        receipt.setAccountTime(marketingTicket.getOpertorTime());
        SwStElectronicReceiptDTO dto = new SwStElectronicReceiptDTO();
        dto.setReceipt(receipt);
        dto.setElectronicReceipts(data);
        SwStElectronicReceipt electronicReceipt = electronicReceiptService.saveSwStElectronicReceipt(dto);
        marketingTicket.setRefElectronicPreviewId(electronicReceipt.getId());
    }

    /**
     * TODO 同步电子预览数据(团购售卖支付方式为现金支付时，只保存线下取票，不保存团购售卖)  弃用
     *
     * @param marketingTicket
     * @param ticketOffineTakeTickets
     */
    private void synElectronicOffineTakeTicket(SwStMarketingTicket marketingTicket,List<SwStMarketingTicketOffineTakeTicket> ticketOffineTakeTickets) {
        List<SwStElectronicReceiptDetails> data = countElectronicOffineTakeTicket(ticketOffineTakeTickets);
        SwStElectronicReceipt receipt = new SwStElectronicReceipt();
        receipt.setAccountTime(marketingTicket.getOpertorTime());
        SwStElectronicReceiptDTO dto = new SwStElectronicReceiptDTO();
        dto.setReceipt(receipt);
        dto.setElectronicReceipts(data);
        SwStElectronicReceipt electronicReceipt = electronicReceiptService.saveSwStElectronicReceipt(dto);
        marketingTicket.setRefElectronicPreviewId(electronicReceipt.getId());
    }

    /**
     * 统计电子预览数据
     * @param ticketGroupSells
     * @param ticketOffineTakeTickets
     * @return
     */
    private List<SwStElectronicReceiptDetails> countElectronicPreviewData(List<SwStMarketingTicketGroupSell> ticketGroupSells, List<SwStMarketingTicketOffineTakeTicket> ticketOffineTakeTickets) {
        List<SwStElectronicReceiptDetails> data = new ArrayList<>();
        // 团购售卖 类型是2
        if (CollectionUtil.isNotEmpty(ticketGroupSells)) {
            for (SwStMarketingTicketGroupSell tg : ticketGroupSells) {
                SwStElectronicReceiptDetails groupSell = SwStElectronicReceiptDetails.builder()
                        .ticketType(tg.getTicketType())
                        .ticketName(tg.getTicketName())
                        .ticketSellNum(tg.getSellNum())
                        .ticketSellAmount(tg.getDiscountAmount())
                        .ticketWayNum(tg.getTicketWayNum())
                        .marketingId(tg.getId())
                        .marketingRelationId(tg.getRelationId())
                        .sellWay("2").build();
                data.add(groupSell);
            }
        }
        //线下正常售卖 类型是 1
        /*if (CollectionUtil.isNotEmpty(ticketOffineSells)) {
            for (SwStMarketingTicketOffineSell offineSell : ticketOffineSells) {
                SwStElectronicReceiptDetails elDetailsOffSell = SwStElectronicReceiptDetails.builder().ticketType(offineSell.getTicketType()).ticketSellNum(offineSell.getTotalSellNum()).ticketSellAmount(offineSell.getTotalSellAmount()).sellWay(1).build();
                data.add(elDetailsOffSell);
            }
        }*/
        //线下取票类型是0
        if (CollectionUtil.isNotEmpty(ticketOffineTakeTickets)) {
            for (SwStMarketingTicketOffineTakeTicket ticket : ticketOffineTakeTickets) {
                SwStElectronicReceiptDetails elReceiptDetails = SwStElectronicReceiptDetails.builder()
                        .ticketType(ticket.getTicketType())
                        .ticketName(ticket.getTicketName())
                        .ticketSellNum(ticket.getTicketNum())
                        .ticketSellAmount(ticket.getSellAmount())
                        .ticketWayNum(ticket.getTicketWayNum())
                        .marketingId(ticket.getId())
                        .marketingRelationId(ticket.getRelationId())
                        .sellWay("0").build();
                //银行转账方式 需要添加转账金额
                if (ticket.getTakeTicketWay().equals("3")) {
                    elReceiptDetails.setTicketTransferAmount(ticket.getSellAmount());
                }
                data.add(elReceiptDetails);
            }
        }
        return data;
    }
    /**
     * 同步电子预览数据(团购售卖支付方式为现金支付时，只保存线下取票，不保存团购售卖)
     * @param ticketOffineTakeTickets
     * @return
     */
    private List<SwStElectronicReceiptDetails> countElectronicOffineTakeTicket(List<SwStMarketingTicketOffineTakeTicket> ticketOffineTakeTickets) {
        List<SwStElectronicReceiptDetails> data = new ArrayList<>();
        //线下取票类型是0
        if (CollectionUtil.isNotEmpty(ticketOffineTakeTickets)) {
            for (SwStMarketingTicketOffineTakeTicket ticket : ticketOffineTakeTickets) {
                SwStElectronicReceiptDetails elReceiptDetails = SwStElectronicReceiptDetails.builder()
                        .ticketType(ticket.getTicketType())
                        .ticketName(ticket.getTicketName())
                        .ticketSellNum(ticket.getTicketNum())
                        .ticketSellAmount(ticket.getSellAmount())
                        .ticketWayNum(ticket.getTicketWayNum())
                        .marketingId(ticket.getId())
                        .marketingRelationId(ticket.getRelationId())
                        .sellWay("0").build();
                //银行转账方式 需要添加转账金额
                if (ticket.getTakeTicketWay().equals("1")) {
                    elReceiptDetails.setTicketTransferAmount(ticket.getSellAmount());
                }
                data.add(elReceiptDetails);
            }
        }
        return data;
    }

    /**
     * 同步售票员日结算数据
     * @param sellId
     * @param refMarkingId
     */
    private void synConductorSettleData(Integer sellId, Integer refMarkingId) {
//        if (CollectionUtil.isEmpty(ticketOffineSells)) {
//            return;
//        }
//        List<SwStConductorSettleDetail> sunList = new ArrayList<>();
//        for (SwStMarketingTicketOffineSell t : ticketOffineSells) {
//            SwStConductorSettleDetail settleDetail = SwStConductorSettleDetail.builder().relationId(rid).ticketType(t.getTicketType())
//                    .ticketName(t.getTicketName()).ticketPrice(t.getTicketPrice()).sellOutNum(t.getTotalSellNum()).cashSellNum(t.getCashSellNum()).cashSellAmount(t.getCashSellAmount())
//                    .alipaySellNum(t.getAlipaySellNum()).alipaySellAmount(t.getAlipaySellAmount()).wechatSellNum(t.getWechatSellNum()).wechatSellAmount(t.getWechatSellAmount())
//                    .sellOutAmount(t.getTotalSellAmount()).createTime(LocalDateTime.now()).delFlag("0").build();
//            sunList.add(settleDetail);
//        }
//      settleDetailService.saveBatch(sunList);
        //version ===  8-2 修改  这块按照table页进行展示所以可能会有一些变动
        //sw_st_conductor_settle
        SwStConductorSettle swStConductorSettle = new SwStConductorSettle();
        swStConductorSettle.setRealtionMarketingId(refMarkingId+"");
        swStConductorSettle.setId(sellId);
        //settleService.updateById(swStConductorSettle);
    }

    /**
     * 计算合计总数量  和合计总金额
     *
     * @param marketingTicket
     * @param ticketOffineSells
     */
    private void countSellDetails(SwStMarketingTicket marketingTicket, List<SwStMarketingTicketOffineSell> ticketOffineSells, List<SwStMarketingTicketGroupSell> ticketGroupSells,List<SwStMarketingTicketOffineTakeTicket> ticketOffineTakeTickets) {
        if (CollectionUtil.isNotEmpty(ticketOffineSells) || CollectionUtil.isNotEmpty(ticketGroupSells)|| CollectionUtil.isNotEmpty(ticketOffineTakeTickets)) {
            Integer totalSellNum = 0;
            BigDecimal totalSellAmount = new BigDecimal(0d);
            for (SwStMarketingTicketOffineSell ticketOffineSell : ticketOffineSells) {
                if (ticketOffineSell.getTotalSellNum() != null) {
                    totalSellNum = totalSellNum + ticketOffineSell.getTotalSellNum();
                }
                if (ticketOffineSell.getTotalSellAmount() != null) {
                    totalSellAmount = totalSellAmount.add(ticketOffineSell.getTotalSellAmount());
                }
            }
            for (SwStMarketingTicketGroupSell ticketGroupSell : ticketGroupSells) {
                if (ticketGroupSell.getSellNum() != null) {
                    totalSellNum = totalSellNum + ticketGroupSell.getSellNum();
                }
                if (ticketGroupSell.getDiscountAmount() != null) {
                    totalSellAmount = totalSellAmount.add(ticketGroupSell.getDiscountAmount());
                }
            }
            for (SwStMarketingTicketOffineTakeTicket ticketOffineTakeTicket : ticketOffineTakeTickets) {
                if (ticketOffineTakeTicket.getTicketNum() != null) {
                    totalSellNum = totalSellNum + ticketOffineTakeTicket.getTicketNum();
                }
                if (ticketOffineTakeTicket.getSellAmount() != null) {
                    totalSellAmount = totalSellAmount.add(ticketOffineTakeTicket.getSellAmount());
                }
            }
            marketingTicket.setTotalSellNum(totalSellNum);
            marketingTicket.setTotalSellAmount(totalSellAmount);
        }

    }

    /**
     * 注意更新的时候是支持新增和删除的场景的
     *
     * @param stMarketingTicketDTO
     * @return
     */
    @Override
    @Transactional
    public boolean updateStMarketingTicket(SwStMarketingTicketDTO stMarketingTicketDTO) {
        //1:更新从表
        SwStMarketingTicket marketingTicket = stMarketingTicketDTO.getMarketingTicket();
        marketingTicket.setBomCode(BeanUtilsStm.bomOrJobNoSort(marketingTicket.getBomCode()));//bom编号排序后修改
        //设备操作号去空格
        marketingTicket.setDeviceOperateNum(BeanUtilsStm.strRemoveBlank(marketingTicket.getDeviceOperateNum()));
        Integer rid = marketingTicket.getId();

        //修改之前添加记录表（先添加主表）
        SwStMarketingTicket marketingTicketOld = getById(rid);
        Integer mainId = 0;
        //报表差错修改开关为“1”打开状态下的时候添加到记录表（先添加主表）
        if("1".equals(marketingTicketOld.getReportModifyStatus())) {
            PigxUser user = SecurityUtils.getUser();
            marketingTicketOld.setEntryUpdateJobNo(user.getUserCode());
            marketingTicketOld.setEntryUpdateJobName(user.getNikeName());
            marketingTicketOld.setEntryUpdateTime(new Date());
            SwStmStationDataEntryLog swStmStationDataEntryLog = new SwStmStationDataEntryLog();
            swStmStationDataEntryLog.setRelationId(marketingTicketOld.getId());
            swStmStationDataEntryLog.setLogTableName(StmTableCommon.SW_ST_MARKETING_TICKET);
            swStmStationDataEntryLog.setLogInfo(JSONObject.toJSONString(marketingTicketOld));
            swStmStationDataEntryLog.setUpdateJobNo(user.getUserCode());
            swStmStationDataEntryLog.setUpdateJobName(user.getNikeName());
            swStmStationDataEntryLog.setUpdateTime(new Date());
            swStmStationDataEntryLogService.save(swStmStationDataEntryLog);
            mainId = swStmStationDataEntryLog.getId();
            if("1".equals(marketingTicketOld.getIsMerge())){
                marketingTicket.setConfirmStatus("1");
            }else {
                marketingTicket.setConfirmStatus("0");
            }
        }else {
            marketingTicket.setConfirmStatus("0");
        }

        //2:更新的场景是存在
        List<SwStMarketingTicketGroupSell> ticketGroupSells = stMarketingTicketDTO.getTicketGroupSells();
        updateGroupSell(mainId, rid, ticketGroupSells);
        List<SwStMarketingTicketOffineSell> ticketOffineSells = stMarketingTicketDTO.getTicketOffineSells();
        updateOffSell(mainId, rid, ticketOffineSells);
        //3:营收车票线下取票明细表更新
        List<SwStMarketingTicketOffineTakeTicket> ticketOffineTakeTickets = stMarketingTicketDTO.getTicketOffineTakeTickets();
        updateOffTakeTicket(mainId, rid, ticketOffineTakeTickets);
        countSellDetails(marketingTicket, ticketOffineSells,ticketGroupSells,ticketOffineTakeTickets);
        //updateById(marketingTicket);
        //4: 同步更新日结算表的数据
        //synConductorSettleData(marketingTicket.getRefConductorSettleId(), rid);
        //5:同步电子预览数据
        List<SwStElectronicReceiptDetails> data = statisticalElectronicReceiptDetails(ticketGroupSells, ticketOffineTakeTickets,null);
        if(CollectionUtil.isNotEmpty(data)){
            if(marketingTicket.getRefElectronicPreviewId()!= null){
                electronicReceiptService.updateSwStElectronicReceipt(data, marketingTicket.getRefElectronicPreviewId());
                updateById(marketingTicket);
            }else {
                //统计电子回执单主表数据和同步更新营销车票主表setRefElectronicPreviewId
                electronicReceiptStatistics(ticketGroupSells,ticketOffineTakeTickets,marketingTicket);
            }
        }else {
            detailsService.remove(new QueryWrapper<SwStElectronicReceiptDetails>().lambda().eq(SwStElectronicReceiptDetails::getRelationId, marketingTicket.getRefElectronicPreviewId()));
            electronicReceiptService.removeById(marketingTicket.getRefElectronicPreviewId());

            //如果电子回执单数据为空，就把营销车票主表数据的关联id置为null
            LambdaUpdateWrapper<SwStMarketingTicket> eq = Wrappers.<SwStMarketingTicket>lambdaUpdate()
                    .set(SwStMarketingTicket::getRefElectronicPreviewId, null)
                    .eq(SwStMarketingTicket::getId, rid);
            update(eq);
        }

        //如果子表都为null，删除主表
        if(CollectionUtil.isEmpty(ticketGroupSells) && CollectionUtil.isEmpty(ticketOffineTakeTickets)){
            List<SwStMarketingTicketOffineSell> orginList = offineSellService.list(new QueryWrapper<SwStMarketingTicketOffineSell>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0));
            if(CollectionUtil.isEmpty(orginList)){
                removeById(rid);
            }
        }
        return true;
    }


    /**
     * 更新
     *
     * @param mainId
     * @param rid
     * @param ticketOffineSells
     */
    private void updateOffSell(Integer mainId, Integer rid, List<SwStMarketingTicketOffineSell> ticketOffineSells) {
        //报表差错修改开关为“1”打开状态下的时候添加到记录表（先添加主表）
        SwStMarketingTicket marketingTicketOld = getById(rid);
        if("1".equals(marketingTicketOld.getReportModifyStatus())) {
            PigxUser user = SecurityUtils.getUser();
            //修改之前添加记录表（再添加子表）
            List<SwStMarketingTicketOffineSell> swStMarketingTicketOffineSells = offineSellService.list(
                    Wrappers.<SwStMarketingTicketOffineSell>lambdaQuery()
                            .eq(SwStMarketingTicketOffineSell::getRelationId, marketingTicketOld.getId())
                            //.eq(SwStTvmCheckDetailCoinChange::getReportModifyStatus, "1")
                            .eq(SwStMarketingTicketOffineSell::getDelFlag,0));

            swStMarketingTicketOffineSells.stream().forEach(offineSell -> {
                offineSell.setEntryUpdateJobNo(user.getUserCode());
                offineSell.setEntryUpdateJobName(user.getNikeName());
                offineSell.setEntryUpdateTime(new Date());
            });
            SwStmStationDataEntryLog swStmStationDataEntryLogChild = new SwStmStationDataEntryLog();
            swStmStationDataEntryLogChild.setRelationId(marketingTicketOld.getId());
            swStmStationDataEntryLogChild.setLogTableName(StmTableCommon.SW_ST_MARKETING_TICKET_OFFINE_SELL);
            swStmStationDataEntryLogChild.setMainId(mainId);//记录表id
            swStmStationDataEntryLogChild.setLogInfo(JSONObject.toJSONString(swStMarketingTicketOffineSells));
            swStmStationDataEntryLogChild.setUpdateJobNo(user.getUserCode());
            swStmStationDataEntryLogChild.setUpdateJobName(user.getNikeName());
            swStmStationDataEntryLogChild.setUpdateTime(new Date());
            swStmStationDataEntryLogService.save(swStmStationDataEntryLogChild);

        }

        if (CollectionUtil.isNotEmpty(ticketOffineSells)) {
            List<SwStMarketingTicketOffineSell> insertData = new ArrayList<>();
            List<SwStMarketingTicketOffineSell> updateData = new ArrayList<>();
            for (SwStMarketingTicketOffineSell ticketOffineSell : ticketOffineSells) {
                Integer id = ticketOffineSell.getId();
                if (id == null) {
                    insertData.add(ticketOffineSell);
                } else {
                    updateData.add(ticketOffineSell);
                }
            }
            if (CollectionUtil.isNotEmpty(updateData)) {
                offineSellService.updateBatchById(updateData);
            }
            List<SwStMarketingTicketOffineSell> orginList = offineSellService.list(new QueryWrapper<SwStMarketingTicketOffineSell>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0));
            List<SwStMarketingTicketOffineSell> removeList = new ArrayList<>();
            List<Integer> updateIds = updateData.stream().map(x -> x.getId()).collect(Collectors.toList());
            for (SwStMarketingTicketOffineSell ticketOffineSell : orginList) {
                if (!updateIds.contains(ticketOffineSell.getId())) {
                    removeList.add(ticketOffineSell);
                }
            }
            if (CollectionUtil.isNotEmpty(removeList)) {
                removeList.forEach(x -> x.setDelFlag("1"));
                offineSellService.updateBatchById(removeList);
            }
            if (CollectionUtil.isNotEmpty(insertData)) {
                for (SwStMarketingTicketOffineSell insert : insertData) {
                    insert.setRelationId(rid);
                    insert.setCreateTime(LocalDateTime.now());
                }
                offineSellService.saveBatch(insertData);
            }
        }
        //因为营销车票转账及团购编辑时没有线下售卖，所以这里不需要做删除处理
        //else {
        //    List<SwStMarketingTicketOffineSell> orginList = offineSellService.list(new QueryWrapper<SwStMarketingTicketOffineSell>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0));
        //    if(CollectionUtil.isNotEmpty(orginList)){
        //        orginList.forEach(x -> x.setDelFlag("1"));
        //        offineSellService.updateBatchById(orginList);
        //    }
        //}
    }

    /**
     * 更新
     *
     * @param mainId
     * @param rid
     * @param ticketGroupSells
     */
    private void updateOffTakeTicket(Integer mainId, Integer rid, List<SwStMarketingTicketOffineTakeTicket> ticketGroupSells) {
        //报表差错修改开关为“1”打开状态下的时候添加到记录表（先添加主表）
        SwStMarketingTicket marketingTicketOld = getById(rid);
        if("1".equals(marketingTicketOld.getReportModifyStatus())) {
            PigxUser user = SecurityUtils.getUser();
            //修改之前添加记录表（再添加子表）
            List<SwStMarketingTicketOffineTakeTicket> swStMarketingTicketOffineTakeTickets = takeTicketService.list(
                    Wrappers.<SwStMarketingTicketOffineTakeTicket>lambdaQuery()
                            .eq(SwStMarketingTicketOffineTakeTicket::getRelationId, marketingTicketOld.getId())
                            //.eq(SwStTvmCheckDetailCoinChange::getReportModifyStatus, "1")
                            .eq(SwStMarketingTicketOffineTakeTicket::getDelFlag,0));

            swStMarketingTicketOffineTakeTickets.stream().forEach(offineTakeTicket -> {
                offineTakeTicket.setEntryUpdateJobNo(user.getUserCode());
                offineTakeTicket.setEntryUpdateJobName(user.getNikeName());
                offineTakeTicket.setEntryUpdateTime(new Date());
            });
            SwStmStationDataEntryLog swStmStationDataEntryLogChild = new SwStmStationDataEntryLog();
            swStmStationDataEntryLogChild.setRelationId(marketingTicketOld.getId());
            swStmStationDataEntryLogChild.setLogTableName(StmTableCommon.SW_ST_MARKETING_TICKET_OFFINE_TAKE_TICKET);
            swStmStationDataEntryLogChild.setMainId(mainId);//记录表id
            swStmStationDataEntryLogChild.setLogInfo(JSONObject.toJSONString(swStMarketingTicketOffineTakeTickets));
            swStmStationDataEntryLogChild.setUpdateJobNo(user.getUserCode());
            swStmStationDataEntryLogChild.setUpdateJobName(user.getNikeName());
            swStmStationDataEntryLogChild.setUpdateTime(new Date());
            swStmStationDataEntryLogService.save(swStmStationDataEntryLogChild);

        }

        if (CollectionUtil.isNotEmpty(ticketGroupSells)) {
            List<SwStMarketingTicketOffineTakeTicket> insertData = new ArrayList<>();
            List<SwStMarketingTicketOffineTakeTicket> updateData = new ArrayList<>();
            for (SwStMarketingTicketOffineTakeTicket ticketOffineTakeTicket : ticketGroupSells) {
                Integer id = ticketOffineTakeTicket.getId();
                if (id == null) {
                    insertData.add(ticketOffineTakeTicket);
                } else {
                    updateData.add(ticketOffineTakeTicket);
                }
            }
            if (CollectionUtil.isNotEmpty(updateData)) {
                takeTicketService.updateBatchById(updateData);
            }
            List<SwStMarketingTicketOffineTakeTicket> orginList = takeTicketService.list(new QueryWrapper<SwStMarketingTicketOffineTakeTicket>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0));
            List<SwStMarketingTicketOffineTakeTicket> removeList = new ArrayList<>();
            List<Integer> updateIds = updateData.stream().map(x -> x.getId()).collect(Collectors.toList());
            for (SwStMarketingTicketOffineTakeTicket ticketOffineTakeTicket : orginList) {
                if (!updateIds.contains(ticketOffineTakeTicket.getId())) {
                    removeList.add(ticketOffineTakeTicket);
                }
            }
            if (CollectionUtil.isNotEmpty(removeList)) {
                removeList.forEach(x -> x.setDelFlag("1"));
                takeTicketService.updateBatchById(removeList);
            }
            if (CollectionUtil.isNotEmpty(insertData)) {
                for (SwStMarketingTicketOffineTakeTicket insert : insertData) {
                    insert.setRelationId(rid);
                    insert.setCreateTime(LocalDateTime.now());
                }
                takeTicketService.saveBatch(insertData);
            }
        }else {
            List<SwStMarketingTicketOffineTakeTicket> orginList = takeTicketService.list(new QueryWrapper<SwStMarketingTicketOffineTakeTicket>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0));
            if(CollectionUtil.isNotEmpty(orginList)){
                orginList.forEach(x -> x.setDelFlag("1"));
                takeTicketService.updateBatchById(orginList);
            }
        }
    }

    /**
     * 更新
     *
     * @param mainId
     * @param rid
     * @param ticketGroupSells
     */
    private void updateGroupSell(Integer mainId, Integer rid, List<SwStMarketingTicketGroupSell> ticketGroupSells) {
        //报表差错修改开关为“1”打开状态下的时候添加到记录表（先添加主表）
        SwStMarketingTicket marketingTicketOld = getById(rid);
        if("1".equals(marketingTicketOld.getReportModifyStatus())) {
            PigxUser user = SecurityUtils.getUser();
            //修改之前添加记录表（再添加子表）
            List<SwStMarketingTicketGroupSell> swStMarketingTicketGroupSells = ticketGroupSellService.list(
                    Wrappers.<SwStMarketingTicketGroupSell>lambdaQuery()
                            .eq(SwStMarketingTicketGroupSell::getRelationId, marketingTicketOld.getId())
                            //.eq(SwStTvmCheckDetailCoinChange::getReportModifyStatus, "1")
                            .eq(SwStMarketingTicketGroupSell::getDelFlag,0));

            swStMarketingTicketGroupSells.stream().forEach(groupSell -> {
                groupSell.setEntryUpdateJobNo(user.getUserCode());
                groupSell.setEntryUpdateJobName(user.getNikeName());
                groupSell.setEntryUpdateTime(new Date());
            });
            SwStmStationDataEntryLog swStmStationDataEntryLogChild = new SwStmStationDataEntryLog();
            swStmStationDataEntryLogChild.setRelationId(marketingTicketOld.getId());
            swStmStationDataEntryLogChild.setLogTableName(StmTableCommon.SW_ST_MARKETING_TICKET_GROUP_SELL);
            swStmStationDataEntryLogChild.setMainId(mainId);//记录表id
            swStmStationDataEntryLogChild.setLogInfo(JSONObject.toJSONString(swStMarketingTicketGroupSells));
            swStmStationDataEntryLogChild.setUpdateJobNo(user.getUserCode());
            swStmStationDataEntryLogChild.setUpdateJobName(user.getNikeName());
            swStmStationDataEntryLogChild.setUpdateTime(new Date());
            swStmStationDataEntryLogService.save(swStmStationDataEntryLogChild);

        }



        if (CollectionUtil.isNotEmpty(ticketGroupSells)) {
            List<SwStMarketingTicketGroupSell> insertData = new ArrayList<>();
            List<SwStMarketingTicketGroupSell> updateData = new ArrayList<>();
            for (SwStMarketingTicketGroupSell ticketGroupSell : ticketGroupSells) {
                Integer id = ticketGroupSell.getId();
                if (id == null) {
                    insertData.add(ticketGroupSell);
                } else {
                    updateData.add(ticketGroupSell);
                }
            }
            if (CollectionUtil.isNotEmpty(updateData)) {
                ticketGroupSellService.updateBatchById(updateData);
            }
            List<SwStMarketingTicketGroupSell> orginList = ticketGroupSellService.list(new QueryWrapper<SwStMarketingTicketGroupSell>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0));
            List<SwStMarketingTicketGroupSell> removeList = new ArrayList<>();
            List<Integer> updateIds = updateData.stream().map(x -> x.getId()).collect(Collectors.toList());
            for (SwStMarketingTicketGroupSell ticketGroupSell : orginList) {
                if (!updateIds.contains(ticketGroupSell.getId())) {
                    removeList.add(ticketGroupSell);
                }
            }
            if (CollectionUtil.isNotEmpty(removeList)) {
                removeList.forEach(x -> x.setDelFlag("1"));
                ticketGroupSellService.updateBatchById(removeList);
            }
            if (CollectionUtil.isNotEmpty(insertData)) {
                for (SwStMarketingTicketGroupSell insert : insertData) {
                    insert.setRelationId(rid);
                    insert.setCreateTime(LocalDateTime.now());
                }
                ticketGroupSellService.saveBatch(insertData);
            }
        }else {
            List<SwStMarketingTicketGroupSell> orginList = ticketGroupSellService.list(new QueryWrapper<SwStMarketingTicketGroupSell>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0));
            if(CollectionUtil.isNotEmpty(orginList)){
                orginList.forEach(x -> x.setDelFlag("1"));
                ticketGroupSellService.updateBatchById(orginList);
            }
        }
    }

    /**
     * @param id
     * @return
     * @Autowired SwStMarketingTicketGroupSellService ticketGroupSellService;
     * @Autowired SwStMarketingTicketOffineSellService offineSellService;
     * @Autowired SwStMarketingTicketOffineTakeTicketService takeTicketService;
     */
    @Override
    @Transactional
    public boolean deleteCascadeById(Integer id) {
        removeById(id);
        //删除从表
        List<SwStMarketingTicketGroupSell> ticketGroupSells = ticketGroupSellService.list(new QueryWrapper<SwStMarketingTicketGroupSell>().eq("RELATION_ID", id).eq("DEL_FLAG", 0));
        List<SwStMarketingTicketOffineSell> ticketOffineSellList = offineSellService.list(new QueryWrapper<SwStMarketingTicketOffineSell>().eq("RELATION_ID", id).eq("DEL_FLAG", 0));
        List<SwStMarketingTicketOffineTakeTicket> ticketOffineTakeTickets = takeTicketService.list(new QueryWrapper<SwStMarketingTicketOffineTakeTicket>().eq("RELATION_ID", id).eq("DEL_FLAG", 0));
        if (CollectionUtil.isNotEmpty(ticketGroupSells)) {
            ticketGroupSells.forEach(x -> x.setDelFlag("1"));
            ticketGroupSellService.updateBatchById(ticketGroupSells);
        }
        if (CollectionUtil.isNotEmpty(ticketOffineSellList)) {
            ticketOffineSellList.forEach(x -> x.setDelFlag("1"));
            offineSellService.updateBatchById(ticketOffineSellList);
        }
        if (CollectionUtil.isNotEmpty(ticketOffineTakeTickets)) {
            ticketOffineTakeTickets.forEach(x -> x.setDelFlag("1"));
            takeTicketService.updateBatchById(ticketOffineTakeTickets);
        }
        return true;
    }

    @Override
    public SwStMarketingTicketDTO queryDetailsById(Integer id) {
        SwStMarketingTicketDTO swStMarketingTicketDTO = new SwStMarketingTicketDTO();
        SwStMarketingTicket marketingTicket = getById(id);
        swStMarketingTicketDTO.setMarketingTicket(marketingTicket);
        List<SwStMarketingTicketGroupSell> ticketGroupSells = ticketGroupSellService.list(new QueryWrapper<SwStMarketingTicketGroupSell>().eq("RELATION_ID", id).eq("DEL_FLAG", 0));
        if (CollectionUtil.isNotEmpty(ticketGroupSells)) {
            swStMarketingTicketDTO.setTicketGroupSells(ticketGroupSells);
        }
        List<SwStMarketingTicketOffineSell> ticketOffineSellList = offineSellService.list(new QueryWrapper<SwStMarketingTicketOffineSell>().eq("RELATION_ID", id).eq("DEL_FLAG", 0));
        if (CollectionUtil.isNotEmpty(ticketOffineSellList)) {
            swStMarketingTicketDTO.setTicketOffineSells(ticketOffineSellList);
        }
        List<SwStMarketingTicketOffineTakeTicket> ticketOffineTakeTickets = takeTicketService.list(new QueryWrapper<SwStMarketingTicketOffineTakeTicket>().eq("RELATION_ID", id).eq("DEL_FLAG", 0));
        if (CollectionUtil.isNotEmpty(ticketOffineTakeTickets)) {
            swStMarketingTicketDTO.setTicketOffineTakeTickets(ticketOffineTakeTickets);
        }
        return swStMarketingTicketDTO;
    }

    @Override
    public SwStMarketingTicketDTO queryNeedToConfirmData(CommomConfirmInfoDTO confirmInfoDTO) {
        LocalDate date = confirmInfoDTO.getDate();
        String lineCode = SecurityUtils.getUser().getLineCode();
        String stationCode = SecurityUtils.getUser().getStationCode();
        confirmInfoDTO.setNsJobNo(BeanUtilsStm.bomOrJobNoSort(confirmInfoDTO.getNsJobNo()));//售票员工号排序
        List<SwStMarketingTicket> data = swStMarketingTicketMapper.selectList(new QueryWrapper<SwStMarketingTicket>().lambda().eq(SwStMarketingTicket::getOpertorTime, date)
                .eq(SwStMarketingTicket::getConductorShifts, confirmInfoDTO.getNsShift()).eq(SwStMarketingTicket::getConductorJobNo, confirmInfoDTO.getNsJobNo())
                .eq(SwStMarketingTicket::getLineCode,lineCode).eq(SwStMarketingTicket::getStationCode,stationCode));
        if (null == data) {
            return null;
        }
        SwStMarketingTicketDTO swStMarketingTicketDTO = new SwStMarketingTicketDTO();
        if(data.size()>1){
            throw new RuntimeException("请检查售票员“" + data.get(0).getConductorName() + "”在该班次存在" + data.size() + "条营销车票数据！");
        }
        if(data.size()>0){
            swStMarketingTicketDTO = queryDetailsById(data.get(0).getId());
        }
        return swStMarketingTicketDTO;
    }

    @Override
    public boolean confirmData(Integer id) {
        SwStMarketingTicket marketingTicket = new SwStMarketingTicket();
        marketingTicket.setId(id);
        //状态确认
        marketingTicket.setConfirmStatus("1");
        updateById(marketingTicket);
        return true;
    }

    @Override
    public boolean updateApprovalStatus(List<Integer> ids, String status) {
        if(CollectionUtils.isEmpty(ids)){
            return false;
        }
        List<SwStMarketingTicket> updateData= new ArrayList<>();
        for (Integer id : ids) {
            SwStMarketingTicket swStMarketingTicket = new SwStMarketingTicket();
            swStMarketingTicket.setId(id);
            swStMarketingTicket.setApprovalStatus(status);
            updateData.add(swStMarketingTicket);
        }
        return updateBatchById(updateData);
    }
}
